#include <iostream>
#include <sys/types.h>
#include <csignal>

// 打印当前进程中挂起的信号
void PrintPending(sigset_t pending)
{
    std:: cout << "我是一个进程: " << getpid() << ", Pending signals: ";
    for (int signo = 31; signo >= 1; --signo)
    {
        // 检查信号是否在挂起集合中
        if (sigismember(&pending, signo))
        {
            std::cout << 1;
        }
        else
        {
            std::cout << 0;
        }
    }
    std::cout << std::endl;
}               

// 信号处理函数
void handlerSig(int signo)
{
    std::cout << "###############################" << std::endl;
    std::cout << "收到信号: " << signo << std::endl;
    // 验证是否处理完成, 2号位才被设置为0
    sigset_t pending;
    sigpending(&pending);
    PrintPending(pending);
    std::cout << "###############################" << std::endl;
}

int main()
{
    signal(SIGINT, handlerSig);

    // 1.屏蔽2号信号
    // 定义信号集：block（新的屏蔽集）、oldblock（保存原始屏蔽集）
    sigset_t block, oldblock;
    // 初始化信号集（清空，确保无任何信号）
    sigemptyset(&block);
    // 向block集合中添加2号信号（SIGINT，对应Ctrl+C）
    sigaddset(&block, SIGINT);
    // 调用sigprocmask设置新的信号屏蔽集
    int n = sigprocmask(SIG_BLOCK, &block, &oldblock);
    if (n == -1) 
    {
        std::cerr << "sigprocmask error" << std::endl;
        return 1;
    }

    // 4.重复获取打印pending信号
    int cnt = 0;
    while (true)
    {
        // 2.定义pending信号集（用于存储当前挂起的信号）
        sigset_t pending;
        // 调用sigpending获取挂起信号集
        int m = sigpending(&pending);
        if (m == -1)
        {
            std::cerr << "sigpending error" << std::endl;
            return 1;
        }

        // 3.打印pending信号
        PrintPending(pending);
        sleep(1);
        ++cnt;
        if (cnt == 10)
        {
            // 5.恢复2号信号
            // 恢复原始原始屏蔽集（解除SIGINT的屏蔽）
            std::cout << "恢复2号信号" << std::endl;

            n = sigprocmask(SIG_SETMASK, &oldblock, nullptr);
            if (n == -1)
            {
                std::cerr << "sigprocmask error" << std::endl;
                return 1;
            }
        }
    }

    return 0;
}